#include "cnetworkdata.h"
#include "const_define.h"
#include <QDataStream>
#include <QDebug>
#include <QWriteLocker>

#define MAX_NETWORK_RECV    1024*1024
#define NOT_INIT_LENGTH     -1

CSyncNetwork::CSyncNetwork(QTcpSocket *parent) :
    QTcpSocket(parent)
{
    _onceMode = false;

    unsigned char mh[4]={0xAA,0xAA,0x55,0x55};
    _magicHeader = QByteArray((char *)mh,4);

    unsigned char mhAck[4]={055,0x55,0xAA,0xAA};
    _magicAckHeader = QByteArray((char *)mhAck,4);

    _io_s = static_cast<QIODevice *>(this);

    this->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
}

//should call in work thread
void CSyncNetwork::readyToWork()
{
    connect(this,SIGNAL(readyRead()),this,SLOT(readNetData()));
}

void CSyncNetwork::setOnceDataMode(bool on)
{
    _onceMode = on;
}

bool CSyncNetwork::writeNetData(QByteArray &data)
{
    if(this->state() == QTcpSocket::ConnectedState)
    {
        this->write(data);
        return this->waitForBytesWritten(MSEC_TCP_WRITE);
    }
    else
    {
        qDebug() << "CSyncNetwork: socket not connected!";
        return false;
    }
}

bool CSyncNetwork::sendPackDataAppend2Sharp(QByteArray &data)
{
    if(_onceMode)
    {
        packageData(data+"##");
    }
    else
    {
        _sendData._d = data+"##";
    }

    return writeNetData(_sendData._d);
}

bool CSyncNetwork::sendPackData(QByteArray &data)
{
    if(_onceMode)
    {
        packageData(data);
    }
    else
    {
        _sendData._d = data;
    }

    return writeNetData(_sendData._d);
}

void CSyncNetwork::packageData(QByteArray data)
{
    static int id = 0;

    QDataStream s(&_sendData._d,QIODevice::ReadWrite);
    _sendData._id = id ++;
    _sendData._length = data.size();

    s << _magicHeader << _sendData._id << _sendData._length << data;

}

void CSyncNetwork::readNetData()
{
    QByteArray head,data;
    int length,id;

    if(!_onceMode)
    {
        data = this->readAll();
    }
    else
    {
        QDataStream s(_io_s);
        s >> head >> id >> length;

        if(head == _magicHeader)
        {
            if(length <= SIZE_MAX_NETWORK_PACKAGE)
            {
                if(this->bytesAvailable()>=length)
                {
                    qDebug() << "CSyncNetwork: readNetData"   << id;
                    s >> data;
                    //emit s_onceData(data);
                }
                else
                {
                    int loop = 3;
                    while(loop > 0 && waitForReadyRead(MSEC_TCP_WRITE))
                    {
                        if(this->bytesAvailable()>=length)
                        {
                            s >> data;
                            //emit s_onceData(data);
                        }
                    }

                    qDebug() << "CSyncNetwork: readNetData fail " << id  <<" length " << length;
                }
            }
            else
            {
                qDebug() << "CSyncNetwork: readNetData length is not correct " << length;
            }
        }
    }

    QStringList list = QString(data).split("##");
    for(int i=0;i<list.size();i++)
    {
        QString s = list.at(i).trimmed();
        if(!s.isEmpty())
            emit s_onceData(s.toLocal8Bit());
    }

}


/*
*/

CNetworkData::CNetworkData()
{
    _length = 0;
    _id = 0 ;
}
